#!/usr/bin/python
## Syslog-Snarf - Copyright (c) 2014, Nicholas Albright
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
## IR tool to sniff SYSLOG off the wire (span) for logging to a SIEM when log files aren't normally captured
from sys import argv, exit, stdout
from socket import socket, AF_INET, SOCK_DGRAM
from re import search
from logging import getLogger, ERROR
from os import geteuid
getLogger("scapy.runtime").setLevel(ERROR) # Scapy is annoying
from scapy.all import *

if len(argv) < 3:
    print "Usage: %s [interface] [remote.syslog.server.ip|filename.log]" % argv[0]
    exit()
if geteuid() != 0:
    print "Root privs are required to sniff the interface. Please run with sudo."
    exit()
logtype = ""
if not search('[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+', argv[2]):
           syslog = open(argv[2], 'w', 1)
           logtype = "local"
else:
    syslog = socket(AF_INET, SOCK_DGRAM)
           logtype = "remote"

def logger(data):
    global logtype
        if "local" in logtype:
                syslog.write(data + "\n")
        if "remote" in logtype:
                syslog.sendto(argv[2],514)
    stdout.flush()

def pparse(packet):
    	try: logger(packet[Raw].load.strip("\n") + " (%s -> %s)"%(packet[IP].src, packet[IP].dst))
    	except: pass ## MISSED!

if __name__ == "__main__":
    while True:
    	try:
    		sniff(iface=argv[1], prn=pparse, filter="udp and port 514", store=0)
    	except:
    		pass

